package com.ss.android.article.base.feature.detail.view;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.OverScroller;

import com.bytedance.common.utility.Logger;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

@TargetApi(value = 9)
public class MyListViewV9 extends ListView {
    private static final boolean isAboveLOLLIPOP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    AbsListView.OnScrollListener mOnScrollListenerDelegate;
    OnScrollBarShowListener mOnScrollBarShowListener;
    private OverScroller mOverScroller;
    private Method mReportScrollStateChangeMethod;
    private Method mFlingRunnable_start_method;
    private Object mFlingRunnable;
    private long mLastOverScrollByTs;
    private int mLastDeltaY;
    private int mScrollRangeY;
    private OnOverScrolledListener mOnOverScrolledListener;
    private AbsListView.OnScrollListener mOnScrollListener = new AbsListView.OnScrollListener() {

        public final void onScroll(AbsListView absListView, int firstVisibleItem,
                                   int visibleItemCount, int totalItemCount) {
            if (MyListViewV9.this.mOnScrollListenerDelegate != null) {
                MyListViewV9.this.mOnScrollListenerDelegate.onScroll(absListView, firstVisibleItem,
                        visibleItemCount, totalItemCount);
            }

            if (MyListViewV9.this.mOnScrollBarShowListener != null) {
                MyListViewV9.this.mOnScrollBarShowListener.onScroll();
            }
        }

        public final void onScrollStateChanged(AbsListView absListView, int scrollState) {
            if (MyListViewV9.this.mOnScrollListenerDelegate != null) {
                MyListViewV9.this.mOnScrollListenerDelegate.onScrollStateChanged(absListView, scrollState);
            }
        }
    };

    public MyListViewV9(Context context) {
        super(context);
        this.init();
    }

    public MyListViewV9(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        this.init();
    }

    public MyListViewV9(Context context, AttributeSet attributeSet, int defaultStyle) {
        super(context, attributeSet, defaultStyle);
        this.init();
    }

    public final boolean supportFling() {
        return (this.mFlingRunnable != null
                && this.mReportScrollStateChangeMethod != null
                && this.mFlingRunnable_start_method != null
                || MyListViewV9.isAboveLOLLIPOP)
                && this.getVisibility() == VISIBLE;
    }

    @SuppressLint(value = {"NewApi"})
    public final boolean tryFling(int velocityY) {
        if (this.supportFling()) {
            if (MyListViewV9.isAboveLOLLIPOP) {
                this.fling(velocityY);
                return true;
            }

            if (this.mReportScrollStateChangeMethod != null
                    && this.mFlingRunnable_start_method != null) {
                try {
                    this.mReportScrollStateChangeMethod.invoke(this, Integer.valueOf(2));
                    this.mFlingRunnable_start_method.invoke(this.mFlingRunnable, Integer.valueOf(velocityY));
                    return true;
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                    if (Logger.debug()) {
                        Logger.d("MyListViewV9", "MyListViewV9:::tryFling(), exception:" + Log.getStackTraceString(throwable));
                    }
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    @SuppressLint(value = {"NewApi"})
    private void init() {
        super.setOnScrollListener(this.mOnScrollListener);
        this.setFriction(ViewConfiguration.getScrollFriction());
        try {
            Field _AbsListView_mEdgeGlowTop_Field = Class.forName(AbsListView.class.getName()).getDeclaredField("mEdgeGlowTop");
            _AbsListView_mEdgeGlowTop_Field.setAccessible(true);
            Object _mEdgeGlowTop_Obj = _AbsListView_mEdgeGlowTop_Field.get(this);
            Class _mEdgeGlowTop_Class = Class.forName(_mEdgeGlowTop_Obj.getClass().getName());
            Field _mGlow_Field = _mEdgeGlowTop_Class.getDeclaredField("mGlow");
            _mGlow_Field.setAccessible(true);
            _mGlow_Field.set(_mEdgeGlowTop_Obj, new ColorDrawable(0));
            Field _Edge_Field = _mEdgeGlowTop_Class.getDeclaredField("mEdge");
            _Edge_Field.setAccessible(true);
            _Edge_Field.set(_mEdgeGlowTop_Obj, new ColorDrawable(0));
        } catch (Exception e) {
        }

        try {
            Field _AbsListView_mFlingRunnable = AbsListView.class.getDeclaredField("mFlingRunnable");
            _AbsListView_mFlingRunnable.setAccessible(true);
            this.mFlingRunnable = _AbsListView_mFlingRunnable.get(this);
            Class _FlingRunnable_Class = Class.forName("android.widget.AbsListView$FlingRunnable");
            this.mFlingRunnable_start_method = _FlingRunnable_Class.getDeclaredMethod("start", Integer.TYPE);
            this.mFlingRunnable_start_method.setAccessible(true);
            Field _AbsListView_mScroller = _FlingRunnable_Class.getDeclaredField("mScroller");
            _AbsListView_mScroller.setAccessible(true);
            this.mOverScroller = (OverScroller) _AbsListView_mScroller.get(this.mFlingRunnable);
            this.mReportScrollStateChangeMethod = AbsListView.class.getDeclaredMethod("reportScrollStateChange", Integer.TYPE);
            this.mReportScrollStateChangeMethod.setAccessible(true);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            this.mOverScroller = null;
            this.mFlingRunnable = null;
            this.mFlingRunnable_start_method = null;
            this.mReportScrollStateChangeMethod = null;
            if (!Logger.debug()) {
                return;
            }
            Logger.d("travis", "MyListViewV9:::init, exception:" + Log.getStackTraceString(throwable));
        }
    }

    public int computeVerticalScrollExtent() {
        return super.computeVerticalScrollExtent();
    }

    public int computeVerticalScrollOffset() {
        return super.computeVerticalScrollOffset();
    }

    public int computeVerticalScrollRange() {
        return super.computeVerticalScrollRange();
    }

    public boolean onInterceptTouchEvent(MotionEvent motionEvent) {
        return this.getVisibility() == VISIBLE && super.onInterceptTouchEvent(motionEvent);
    }

    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        if (this.mOnOverScrolledListener != null) {
            this.mOnOverScrolledListener.onOverScrolled(this, scrollY, clampedY,
                    this.mLastDeltaY, this.mScrollRangeY);
        }
    }

    public boolean onTouchEvent(MotionEvent motionEvent) {
        return this.getVisibility() == VISIBLE && super.onTouchEvent(motionEvent);
    }

    @SuppressLint(value = {"NewApi"})
    protected boolean overScrollBy(int deltaX,
                                   int deltaY,
                                   int scrollX,
                                   int scrollY,
                                   int scrollRangeX,
                                   int scrollRangeY,
                                   int maxOverScrollX,
                                   int maxOverScrollY,
                                   boolean isTouchEvent) {
        this.mLastDeltaY = deltaY;
        this.mScrollRangeY = scrollRangeY;
        Logger.d("travis", new StringBuilder("MyListViewV9:::overScrollBy(), mLastDeltaY = ").append(this.mLastDeltaY)
                .append(", scrollRangeY = ").append(scrollRangeY).toString());
        int v10 = deltaY >= 0 || scrollY >= 0 ? maxOverScrollY : 0;
        if (this.mOnOverScrolledListener != null
                && deltaY < 0
                && this.getFirstVisiblePosition() == 0
                && scrollY == 0) {
            int velocityY = 0;
            if (this.mOverScroller != null) {
                velocityY = ((int) (-this.mOverScroller.getCurrVelocity()));
                if (Logger.debug()) {
                    Logger.d("MyListViewV9", "overScrollBy:canUseOverScroller: " + velocityY);
                }
            }

            if (velocityY == 0) {
                velocityY = 0;
                long v4 = SystemClock.uptimeMillis() - this.mLastOverScrollByTs;
                if (v4 > 0) {
                    velocityY = ((int) (1000 / v4));
                }

                if (velocityY <= 0) {
                    velocityY = 0;
                } else if (velocityY > 60) {
                    velocityY = 60;
                }

                velocityY *= deltaY;
            }

            if (velocityY != 0) {
                new StringBuilder("overScrollBy, velocityY = ").append(velocityY)
                        .append(", call mOverScrolledListener.fling(velocityY)");
                this.mOnOverScrolledListener.fling(velocityY);
            }

            if (Logger.debug()) {
                Logger.d("travis", "MyListViewV9:::overScrollBy:" + deltaY + "/" + scrollY
                        + "/" + scrollRangeY + "/" + velocityY);
            }
        }
        this.mLastOverScrollByTs = SystemClock.uptimeMillis();
        return super.overScrollBy(deltaX, deltaY,
                scrollX, scrollY,
                scrollRangeX, scrollRangeY,
                maxOverScrollX, v10, isTouchEvent);
    }

    public void setOnOverScrolledListener(OnOverScrolledListener onOverScrolledListener) {
        this.mOnOverScrolledListener = onOverScrolledListener;
    }

    public void setOnScrollBarShowListener(OnScrollBarShowListener onScrollBarShowListener) {
        this.mOnScrollBarShowListener = onScrollBarShowListener;
    }

    public void setOnScrollListener(AbsListView.OnScrollListener onScrollListener) {
        this.mOnScrollListenerDelegate = onScrollListener;
    }
}

